#region File Description
//-----------------------------------------------------------------------------
// SkinningSample.cs
//
// Microsoft XNA Community Game Platform
// Copyright (C) Microsoft Corporation. All rights reserved.
//-----------------------------------------------------------------------------
#endregion

#region Using Statements
using System;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Content;
using Microsoft.Xna.Framework.Graphics;
using Microsoft.Xna.Framework.Input;

//You will need to add this using
using SkinnedModel;

#endregion

namespace SkinningSample
{
    public class SkinningSampleGame : Microsoft.Xna.Framework.Game
    {
        #region Fields

        GraphicsDeviceManager graphics;

        KeyboardState currentKeyboardState = new KeyboardState();
        GamePadState currentGamePadState = new GamePadState();

        Model currentModel;

        //Add these as well two things
        AnimationPlayer animationPlayer;
        Matrix[] _originalBonesMatrix;

        float cameraArc = 0;
        float cameraRotation = 0;
        float cameraDistance = 100;


        float bendX = 0;

        #endregion

        #region Initialization


        public SkinningSampleGame()
        {
            graphics = new GraphicsDeviceManager(this);
            Content.RootDirectory = "Content";

#if WINDOWS_PHONE
            // Frame rate is 30 fps by default for Windows Phone.
            TargetElapsedTime = TimeSpan.FromTicks(333333);
            
            graphics.IsFullScreen = true;            
#endif
        }

        protected override void LoadContent()
        {
            currentModel = Content.Load<Model>("bow");

            //Add everything from here
            SkinningData skinningData = currentModel.Tag as SkinningData;

            _originalBonesMatrix = new Matrix[skinningData.BindPose.Count];

            int currentBone = 0;
            while (currentBone < skinningData.BindPose.Count)
            {
                _originalBonesMatrix[currentBone] = skinningData.BindPose[currentBone];
                currentBone++;
            }

            if (skinningData == null)
                throw new InvalidOperationException
                    ("This model does not contain a SkinningData tag.");

            animationPlayer = new AnimationPlayer(skinningData);

            skinningData.BindPose.CopyTo(animationPlayer.boneTransforms, 0);

            //to here
        }


        #endregion

        #region Update and Draw

        protected override void Update(GameTime gameTime)
        {
            HandleInput();

            UpdateCamera(gameTime);

            float time = (float)gameTime.ElapsedGameTime.TotalMilliseconds;

            //Add this line, this is to get the ID of the bow string, why its -2, its because its weird that way
            int boneId = currentModel.Bones["bowString"].Index - 2;

            //These next few lines updates the bow string.
            //What it does is translate the bow string in relation to its original position
            //So to reset the string to its original position, just make bendX = 0
            // ive already tried numbers for max and min and it should be good if its between -4 and 7
            animationPlayer.boneTransforms[boneId] = Matrix.CreateTranslation(bendX, 0, 0) * _originalBonesMatrix[boneId];
            animationPlayer.UpdateWorldTransforms(Matrix.Identity);
            animationPlayer.UpdateSkinTransforms();
            //thats is all there is to add in the update

            base.Update(gameTime);
        }

        protected override void Draw(GameTime gameTime)
        {
            GraphicsDevice device = graphics.GraphicsDevice;

            device.Clear(Color.CornflowerBlue);

            Matrix view = Matrix.CreateLookAt(new Vector3(10, 0, 1), new Vector3(0, 0, 0), new Vector3(0, 1, 0));
            Matrix projection = Matrix.CreatePerspectiveFieldOfView(MathHelper.ToRadians(45), 800f / 600f, 0.1f, 100f);

            //I moved the draw function to AnimationPlayer. Like that, you can just call it to draw the bow
            // If you want to modify some effect, the draw function is at the end of AnimationPlayer.cs
            animationPlayer.draw(currentModel, view, projection);

            base.Draw(gameTime);
        }

        
        #endregion

        #region Handle Input

        private void HandleInput()
        {
            currentKeyboardState = Keyboard.GetState();
            currentGamePadState = GamePad.GetState(PlayerIndex.One);

            if (currentKeyboardState.IsKeyDown(Keys.Escape) ||
                currentGamePadState.Buttons.Back == ButtonState.Pressed)
            {
                Exit();
            }
        }

        private void UpdateCamera(GameTime gameTime)
        {
            float time = (float)gameTime.ElapsedGameTime.TotalMilliseconds;

            if ((currentKeyboardState.IsKeyDown(Keys.Right) ||
                currentKeyboardState.IsKeyDown(Keys.D)) && bendX < 7)
            {
                bendX += time * 0.1f;
            }
            
            if ((currentKeyboardState.IsKeyDown(Keys.Left) ||
                currentKeyboardState.IsKeyDown(Keys.A)) && bendX > -4)
            {
                bendX -= time * 0.1f;
            }

            if (currentKeyboardState.IsKeyDown(Keys.R))
            {
                bendX = 0;
            }
        }


        #endregion
    }


    #region Entry Point

    static class Program
    {
        static void Main()
        {
            using (SkinningSampleGame game = new SkinningSampleGame())
            {
                game.Run();
            }
        }
    }

    #endregion
}
